home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
111_01
/
se.c
< prev
next >
Wrap
Text File
|
1985-08-19
|
12KB
|
600 lines
/*
HEADER: ;
TITLE: Diskette sector editor;
VERSION: 1.4;
DESCRIPTION: "Lets you view, edit and write back a diskette sector.
It needs a 24*80 cursor-addressable terminal, and requires
your custom CLRSCREEN() and GOTOXY() functions. The
definitions of these functions appear early in SE.C.
Compiling requires SENTER.C, included on the diskette.
Also included are SE.DOC and SE.SUB.";
KEYWORDS: Disk, utility, editor, sector;
SYSTEM: CP/M-80, V2.2;
FILENAME: SE.C;
WARNINGS: "Requires Version 2.x of CP/M.
SE is not designed to work with systems using the DEBLOCK
routine in the BIOS to handle physical sectors larger than
128 bytes, so if you have such a system, and want to use SE,
you must modify the routines in SE which write back the edited
sector. The BitMap command is not implemented.";
SEE-ALSO: SE.DOC, SENTER.C;
AUTHORS: Jan Larsson;
COMPILERS: BDS C, v1.43 and 1.5a;
*/
/************************************************************************
Version 1.0:
SE uses 2.x functions which are not available on CP/M 1.x,
so it will need patching for running under 1.x. Functions
for handling XY and CLEAR screen are at the beginning of SE.C.
Jan Larsson, Kosterv. 12, S-181 35 Lidingo, SWEDEN
************************************************************************/
#include <bdscio.h>
#define YOFF 6
#define XOFF 7
#define AYOFF 6
#define AXOFF 60
#define LEFT 0x13
#define RIGHT 0x04
#define UP 0x05
#define DOWN 0x18
#define ESC 0x1B
struct dp {
unsigned spt ;
char blocks ;
char blockm ;
char nullm ;
unsigned dsiz ;
unsigned dirsiz ;
char all0 ;
char all1 ;
unsigned checksiz ;
unsigned tracko ;
};
struct dp *pdp ;
unsigned maxtrack, maxsec, spb, ctrack, csec, cblock, trans, *ptrans ;
char cbuf[128], line[128], tbuf[80] ;
char a,b,c ;
unsigned x,y,z ;
/*
** Send a character to the video terminal
*/
pchar( c )
char c ;
{
bios( 4, c );
}
/*
** Get a char from keyboard
*/
gchar()
{
return( toupper( bios(3) ) );
}
/*
** Clear the screen
*/
clrscreen()
{
pchar( 26 );
}
/*
** Cursor adressing routine, y = vertical 0...n, x = horizontal 0...n
*/
gotoxy( x, y )
char x, y ;
{
pchar( ESC );
pchar( '=' );
pchar( y + 32 );
pchar( x + 32 );
}
/*
** Handle cursor positioning on a HEX map of memory
** on the screen, 128 bytes as 8 rows of 16 bytes.
** One space between bytes on screen
*/
hxy( pos )
unsigned pos;
{
char x, y ;
y = pos / 32 + YOFF ;
x = pos % 32 ;
x += x/2 + XOFF ;
gotoxy( x, y );
}
/*
** Cursor positioning on the ASCII display, 8 rows of 16 chars
*/
axy( pos )
unsigned pos ;
{
char x, y ;
pos /= 2 ;
y = pos / 16 + AYOFF ;
x = pos % 16 + AXOFF ;
gotoxy( x, y );
}
/*
** The real workhorse editing routine, handles (almost) everything.
*/
unsigned hget( pos, buf )
unsigned pos ;
char *buf ;
{
char c, d ;
d = c = gchar();
if(c == 3)stop();
if(c >= '0' && c <= '9')c -= '0' ;
else if(c >= 'A' && c <= 'F')c = (c - 'A') + 10 ;
else {
switch( c ) {
case RIGHT : if(pos < 255)pos++ ; hxy( pos ); return( pos );
case LEFT : if(pos > 0)pos-- ; hxy( pos ); return( pos );
case UP : if(pos > 31)pos -= 32 ; hxy( pos ); return( pos );
case DOWN : if(pos < 224)pos += 32 ; hxy( pos ); return( pos );
case ESC : hxy( pos ); return( ERROR );
case 0x01 : pos -= (pos % 32) ; hxy( pos ); return( pos );
case 0x06 : pos += (32 - (pos % 32)) - 1 ; hxy( pos ); return( pos );
case 0x1a : pos = 0 ; hxy( pos ); return( pos );
default : ermsg("Illegal HEX digit.");
enter( 0, 18, " Command: ", 48, line, 0x62 );
hxy( pos ); return( pos );
}
}
if(pos % 2 == 0)buf[ pos/2 ] = (buf[ pos/2 ] & 0x0f) | (c << 4) ;
else buf[ pos/2 ] = (buf[ pos/2 ] & 0xf0) | c ;
hxy( pos ); pchar( d );
axy( pos );
if(buf[ pos/2 ] >= ' ' && buf[ pos/2 ] <= 0x7e)pchar( buf[ pos/2 ] ) ;
else pchar('.');
if(pos < 255)pos++ ;
hxy( pos );
return( pos );
}
/*
** Display a 128 byte buffer on screen
*/
display( buf )
char *buf ;
{
unsigned ppos ;
char c, i ;
gotoxy( 0, YOFF );
ppos = 0 ;
while(ppos < 255){
printf("%04x: ", ppos/2 );
hxy( ppos );
for(i = 0 ; i < 16 ; i++ )printf("%02x ", buf[ ppos/2 + i ] );
axy( ppos );
for(i = 0 ; i < 16 ; i++ ){
c = buf[ ppos/2 + i ] ;
if(c >= ' ' && c <= 0x7e)pchar( c );
else pchar('.');
}
ppos += 32 ;
printf("\n");
}
ppos = 0 ;
hxy( ppos );
}
/*
** Stop immediately, and return to DOS
*/
stop()
{
gotoxy(0,22);
exit();
}
/*
** Display ERROR message on screen
*/
ermsg( s )
char *s ;
{
gotoxy( 10, 18 );
printf("ERR: %s ", s );
gchar();
}
/*
** CHECKPAR checks the track sector parameters
*/
checkpar( track, sector )
unsigned track, sector ;
{
if(track > maxtrack){ ermsg("Too large track number.");
return( FALSE );
}
if(sector > maxsec){ ermsg("Too large sector number");
return( FALSE );
}
if(sector == 0){ ermsg("Sector number cant be 0");
return( FALSE );
}
return(TRUE);
}
/*
** PSEC stores a sector, using actual skewing factor
*/
psec( track, sector, buffer )
unsigned track, sector ;
char *buffer ;
{
if(track >= pdp -> tracko)sector = sectran( (sector - 1) );
bios( 10, track );
bios( 11, sector );
bios( 12, buffer );
bios( 14 );
}
/*
** GSEC fetches a sector, using actual skewing factor
*/
gsec( track, sector, buffer )
unsigned track, sector ;
char *buffer ;
{
if(track >= pdp -> tracko)sector = sectran( (sector - 1) );
bios( 10, track );
bios( 11, sector );
bios( 12, buffer );
bios( 13 );
}
/*
** Header displays the header at the top of the page
*/
header()
{
printf("Ayatollans Mjukisar");
gotoxy( 26,0 );
printf("S E C T O R E D I T O R");
gotoxy( 68, 0 );
printf("Version 1.4");
gotoxy( 0, 1 );
printf("----------------------------------------");
printf("----------------------------------------");
}
/*
** Display the commands at the lowest line of the
** the screen.
*/
docs()
{
gotoxy( 0, 21 );
printf(" NewDisk/Look/Edit/Write/Bye/BitMap/Drive");
}
/*
** copy the n-th item of command line into spec mini-buf
*/
ctok( buf, line, n )
char *buf, *line ;
char n ;
{
char *p1, *p2, i, ccc, bool ;
bool = FALSE ;
*buf = NULL ;
p1 = line ;
while(*p1 == ' ' && *p1 != NULL)p1++ ;
i = 1 ;
while(i < n && *p1 != NULL){
while(*p1 != ' ' && *p1 != NULL)p1++ ;
while(*p1 == ' ' && *p1 != NULL)p1++ ;
i++ ;
}
if(*p1 != NULL){
p2 = p1 ;
while(*p2 != ' ' && *p2 != NULL)p2++ ;
ccc = *p2 ;
*p2 = NULL ;
strcpy( buf, p1 );
*p2 = ccc ;
}
}
/*
** Display the maximum numbers
*/
dispmax()
{
gotoxy( 0, 3 );
printf("CP/M Max block:%4d Disk Size:%5d kbyte",
pdp -> dsiz,
(pdp -> dsiz + 1) * (spb / 8) );
printf(" Max Track:%3d Max Sector:%3d", maxtrack, maxsec );
}
/*
** After getting new track/sector adresses, calc and display new
** block numbers etc.
*/
calc()
{
gotoxy( 0, 16 );
cblock = ((ctrack - pdp -> tracko) * maxsec + csec) / spb ;
printf("CP/M Block number: %4d/%x ", cblock, cblock );
printf("Track number: %3d ", ctrack );
printf("Sector number: %3d ", csec );
}
/*
** SELDSK call bios routine for seldsk, return whatever
** BIOS returns in HL
*/
seldsk( drive )
char drive ;
{
unsigned *p, d ;
p = 1 ;
d = *p ;
d = d + 24 ;
return( call( d, 0, 0, drive, 0 ) );
}
/*
** SECTRAN calls the sectran routine in users BIOS
*/
sectran( secno )
char secno ;
{
unsigned p ;
ptrans = 1 ;
p = *ptrans ;
p += 0x2d ;
return( call( p, 0, 0, secno, trans ) );
}
bitmap(){;;}
/*
** Ini